#ifndef CONFIG_H_
#define CONFIG_H_

#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include "version.h"
#include "../fatfs/ff.h"
#include "../drivers/iap/iap.h"
#include "../drivers/iap/sectors.h"

#define CONFIG_FILE   "0:bootcfg.txt"
#define SETTINGS_FILE "settings.bin"
#define SETTINGS_DIR0 "0:ARCHIV8"
#define SETTINGS_DIR1 "SETTINGS"

#define SOFTWARE_ID VERSION
#define HARDWARE_ID 2
#define DEVICE_ID   1115
#define CONFIG_ADDRESS     0x00078000		// FLASH-address to store parameters
#define CONFIG_LENGTH	   4096		// SHOULD BE 256, 512, 1024 or 4096 (!!!)

#define APN_NAME_MAX_LEN      32
#define SERVER_NAME_MAX_LEN   32

//#define BOOTMODEM_CONNECT_BAUD  38400
//#define SetBaudSrt              "AT+IPR=38400\r\n"
//#define BOOTMODEM_CONNECT_BAUD  57600
//#define SetBaudSrt              "AT+IPR=57600\r\n"
#define BOOTMODEM_CONNECT_BAUD  19200
#define SetBaudSrt              "AT+IPR=19200\r\n"
typedef struct {
  float K[16];
} AIN_CAL_t;

typedef struct {
  unsigned int Baud;
} Serial_t;

typedef struct {
  int RPC;
  int GPIO;
  int Com1;
  int Com2;
  int Com3;
} Schedule_t;

typedef struct {
  char APN[APN_NAME_MAX_LEN];
  char Server[SERVER_NAME_MAX_LEN];
  unsigned int JsonPort;
  unsigned int HttpPort;
} SimConfig_t;

typedef struct {
  unsigned int Baud;
  unsigned int TcpTimeout;
  SimConfig_t Sim[2];
} ModemConfig_t;



typedef struct {
  /** Firmware CRC */
  unsigned int Crc32;
  /** Hardware revision */
  unsigned int Hardware;
  /** Device id */
  unsigned int DeviceId;
  /** Serial */
//  Serial_t Com1;
//  Serial_t Com2;
//  Serial_t Com3;
  /** GSM Modem */
  ModemConfig_t Network;
  /** Schedule */
//  Schedule_t Schedule;
  /** AIN Calibration */
//  AIN_CAL_t Calibration;
  unsigned  int Update; //  необходимость абдейта
  unsigned int  crc32;  // CRC конфигурации для сохранения во Flesh контроллера
} Config_t;

//void config_init();
//bool config_save_eeprom();
void config_load_eeprom();
bool config_load_bin(Config_t *cfg);
void config_init(Config_t *cfg);
//8********************************************************************************
//8********************************************************************************
//
// добавления к сохранению конфигурации и векторов
//
//8********************************************************************************
//8********************************************************************************

#define MIN_CFGFILE_LEN   23

// адрес, где сохраняются вектора прерываний
#define IVT_STORE_ADDR  0x0007D000L
#define IVT_STORE_SIZEW 16
#define IVT_STORE_SIGN  0xDeadC0de

#define IVT_SECTOR_DATA_LEN (256-IVT_STORE_SIZEW-4- ((sizeof(Config_t))>>2) -  ( (sizeof(Config_t)&0x03)?1:0 )  )
typedef struct{ // структура данных в секторе хранения векторов прерываний
  unsigned  int ivt[IVT_STORE_SIZEW];   // таблица векторов из прошивки
  unsigned  int sign;         // сигнатура для определения валидности таблицы векторов
  unsigned  int crc32;        // сохраненная CRC32 последней прошивки
  unsigned  int HwID;         // Hardware ID
  unsigned  int DvID;         // Device ID
  Config_t  cfg;
  unsigned  int data[IVT_SECTOR_DATA_LEN]; // дополнение до 1024 байт
}IVTSector;

typedef enum{
  CFGStringParameter=0,
  CFGUnsignedIntParameter =1
}CFGParameterType;

typedef struct{// описание параметра конфигурации
  const unsigned char * const name; // строковое имя параметра
  CFGParameterType  type;         // тип параметра
  const unsigned int  len;        // максимальная длина области хранения параметра
}CFGParameter;

unsigned int config_load(Config_t *cfg, unsigned char *bf, unsigned int sz);
bool FindParameter(unsigned char *bf, const CFGParameter *tf, void *dest);
unsigned int  CmpParam(const unsigned char *s1,const unsigned char *s2);
unsigned int  FindNextString(const unsigned char *s);
unsigned int  StoreStringParameter(const unsigned char *bf, unsigned char *dest, unsigned int maxlen, unsigned int *load);
bool StoreIntParameter(const unsigned char *bf, unsigned int *dest, unsigned int maxlen, unsigned int *load);
bool ParseConfig(Config_t *cfg, unsigned char *bf, unsigned int br);
unsigned int  GetConfigCRC32(Config_t *cfg);

#endif /* CONFIG_H_ */
